package com.db.bankapp.network.server;

import com.db.bankapp.domain.Bank;
import com.db.bankapp.service.BankDataLoaderService;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class BankServer {
    private static final ExecutorService executor = Executors.newCachedThreadPool();
    private static final AtomicBoolean stopped = new AtomicBoolean();

    public static void startServer(Bank bank) {
        try (ServerSocket listener = new ServerSocket(13000)) {
            while (!stopped.get()) {
                Socket socket = listener.accept();
                executor.submit((Runnable) () -> {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                         BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
                        while (true) {
                            String message = reader.readLine();
                            if (message.split(" ")[0].equals("add")) {
                                BankDataLoaderService.feedBank(bank, new Scanner(message.split(" ")[1]));
                                writer.write("Server has added the client\n");
                                writer.flush();
                            } else {
                                writer.write("Unknown command\n");
                                writer.flush();
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void stop(long timeoutMillis) {
        stopped.set(true);
        executor.shutdown();
        try {
            executor.awaitTermination(timeoutMillis, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace();
            return;
        }
        executor.shutdownNow();
    }

    private BankServer() {}
}
